/*
 * Recibe un ResultSet de la clase Query y evuelve un array de pojos 
 */
package util;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import pojos.Atributo;
import pojos.Categoria;
import pojos.Descargas;
import pojos.ListWrapper;
import pojos.Movimientos;
import pojos.Pedido;
import pojos.Pojo;
import pojos.Producto;
import pojos.ProductoCategoria;
import pojos.ProductoDetalle;
import pojos.TipoAtributo;
import pojos.TipoProducto;
import pojos.TipoProductoCategoria;
import pojos.TipoProductoTipoAtributo;
import pojos.Usuario;

/**
 * @author Miguel
 */
public class PojosFactory {
    
    private static ThreadLocal<SimpleDateFormat> tsdf=new ThreadLocal<>();
    
    public static SimpleDateFormat getSdf() {
        if(tsdf.get()==null) {
    		tsdf.set(new SimpleDateFormat("yyyy-MM-dd"));
    	} 
        return tsdf.get();
    }
   
    /*
    * Devuelve un array de Productos
    */
    public static Producto[] getProductosFromRS(ResultSet rs) throws SQLException, ParseException {
        List<Producto> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;
            list.add(new Producto(rs.getInt("id"), rs.getInt("prod_vendedor"),
                    rs.getInt("prod_tipo_producto"), 
                    rs.getString("prod_nombre"), rs.getString("prod_descripcion"),
                    rs.getInt("prod_estado"), rs.getDouble("prod_precio"), rs.getLong("prod_visitas"),
                    getSdf().parse(rs.getString("prod_fecha_alta")), rs.getDouble("prod_valoracion")));
        }
        rs.close();
        Producto[] productos=new Producto[count];        
        return list.toArray(productos);
    }
    
    /*
    * Devuelve un array de Usuarios
    */
    public static Usuario[] getUsuariosFromRS(ResultSet rs) throws SQLException, ParseException {
        List<Usuario> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new Usuario(rs.getInt(1), rs.getString(2), rs.getString(3), 
                    rs.getString(4), rs.getInt(5), rs.getString(6), 
                    rs.getString(7), getSdf().parse(rs.getString(8)), 
                    getSdf().parse(rs.getString(9)), rs.getDouble(10)));
        }
        Usuario[] users=new Usuario[count];
        rs.close();
        return list.toArray(users);
    }
    
    /*
    * Devuelve un array de Atributos
    */
    public static Atributo[] getAtributosFromRS(ResultSet rs) throws SQLException, ParseException{
        List<Atributo> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new Atributo(rs.getString(1), rs.getInt(2), rs.getInt(3)));
        }
        Atributo[] atrb=new Atributo[count];
        rs.close();
        return list.toArray(atrb);
    }
    
    /*
    * Devuelve un array de Categorias
    */
    public static Categoria[] getCategoriasFromRS(ResultSet rs) throws SQLException, ParseException{
        List<Categoria> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new Categoria(rs.getInt(1), rs.getString(2)));
        }
        Categoria[] category=new Categoria[count];
        rs.close();
        return list.toArray(category);
    }
    
    /*
    * Devuelve un array de Descargas
    */
    public static Descargas[] getDescargasFromRS(ResultSet rs) throws SQLException, ParseException{
        List<Descargas> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new Descargas(rs.getInt(1), rs.getInt(2), rs.getInt(3), 
                                   rs.getString(4), getSdf().parse(rs.getString(5)), 
                                   rs.getDouble(6), rs.getDouble(7), rs.getString(8)));
        }
        Descargas[] downloads=new Descargas[count];
        rs.close();
        return list.toArray(downloads);
    }
    
    /*
    * Devuelve un array de Movimientos
    */
    public static Movimientos[] getMovimientosFromRS(ResultSet rs) throws SQLException, ParseException{
        List<Movimientos> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new Movimientos(rs.getInt(1), rs.getInt(2), getSdf().parse(rs.getString(3)), 
                                   rs.getDouble(4), rs.getInt(5)));
        }
        Movimientos[] moves=new Movimientos[count];
        rs.close();
        return list.toArray(moves);
    }
    
    /*
    * Devuelve un array de Pedidos
    */
    public static Pedido[] getPedidosFromRS(ResultSet rs) throws SQLException, ParseException{
        List<Pedido> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new Pedido(rs.getInt(1), rs.getInt(2), rs.getString(3)));
        }
        Pedido[] deliverys=new Pedido[count];
        rs.close();
        return list.toArray(deliverys);
    }
    
    /*
    * Devuelve un array de ProductoCategoria
    */
    public static ProductoCategoria[] getProductoCategoriaFromRS(ResultSet rs) throws SQLException, ParseException{
        List<ProductoCategoria> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new ProductoCategoria(rs.getInt(1), rs.getInt(2)));
        }
        ProductoCategoria[] proCat=new ProductoCategoria[count];
        rs.close();
        return list.toArray(proCat);
    }
    
    /*
    * Devuelve un array de ProductoDetalle
    */
    public static ProductoDetalle[] getProductoDetalleFromRS(ResultSet rs) throws SQLException, ParseException{
        int categorias_count=0;
        int comentarios_count=0;        
        int id = 0;    
        int prod_vendedor = 0;
        int prod_tipo_producto = 0;    
        String prod_nombre = null;
        String prod_descripcion = null;
        int prod_estado = 0;
        double prod_precio = 0;
        long prod_visitas = 0;
        Date prod_fecha_alta = null;
        double prod_valoracion = 0;
        HashMap<String, String> atributos=null;
        List<String> categorias_list=new ArrayList<>();
        List<String> comentarios_list=null;
        String tipo_producto=null;
        String usu_nombre=null;
        while(rs.next()) {
                       
//            Falta rellenar los null, por orden son:
//            Map<String, String> atributos, String[] categorias, Map<String, String> desc_comentarios
            id=rs.getInt(1);
            prod_vendedor=rs.getInt(2);
            prod_tipo_producto=rs.getInt(3);
            prod_nombre=rs.getString(4);
            prod_descripcion=rs.getString(5);
            prod_estado=rs.getInt(6);
            prod_precio=rs.getDouble(7);
            prod_visitas=rs.getLong(8);
            prod_fecha_alta=getSdf().parse(rs.getString(9));
            prod_valoracion=rs.getDouble(10);
            tipo_producto=rs.getString(11);
            String atr_nombre=rs.getString(12);
            String atr_valor=rs.getString(13);
            String categoria=rs.getString(14);
            String comentario=rs.getString(15);
            usu_nombre=rs.getString(16);
            if(atr_nombre!=null && atr_valor!=null) {
                if(atributos==null) {
                    atributos=new HashMap<>();
                }
                if(!atributos.containsKey(atr_nombre)) {
                    atributos.put(atr_nombre, atr_valor);                      
                }                
            }
            if(!categorias_list.contains(categoria)) {
                categorias_list.add(categoria);
                categorias_count++;
            }            
            if(comentario!=null) {
                if(comentarios_list==null) {
                    comentarios_list=new ArrayList<>();
                }
                if(!comentarios_list.contains(comentario)) {
                    comentarios_list.add(comentario);
                    comentarios_count++;
                }                
            }
        }
        
        ProductoDetalle[] proDet=new ProductoDetalle[1];
        String[] categorias=new String[categorias_count];
        String[] desc_comentarios=new String[comentarios_count];
        String[] comentarios=new String[comentarios_count];
        if(comentarios_list!=null) {
            comentarios=comentarios_list.toArray(desc_comentarios);
        }
        proDet[0]=new ProductoDetalle(id, prod_vendedor, prod_tipo_producto, prod_nombre,
                prod_descripcion, prod_estado, prod_precio, prod_visitas, 
                prod_fecha_alta, prod_valoracion, atributos, categorias_list.toArray(categorias), 
                tipo_producto, usu_nombre, comentarios);
        rs.close();
        return proDet;
    }
    
    /*
    * Devuelve un array de TipoAtributo
    */
    public static TipoAtributo[] getTipoAtributoFromRS(ResultSet rs) throws SQLException, ParseException{
        List<TipoAtributo> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new TipoAtributo(rs.getInt(1), rs.getString(2), rs.getString(3)));
        }
        TipoAtributo[] typeAtr=new TipoAtributo[count];
        rs.close();
        return list.toArray(typeAtr);
    }
    
    /*
    * Devuelve un array de TipoProducto
    */
    public static TipoProducto[] getTipoProductoFromRS(ResultSet rs) throws SQLException, ParseException{
        List<TipoProducto> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new TipoProducto(rs.getInt(1), rs.getString(2)));
        }
        TipoProducto[] typePro=new TipoProducto[count];
        rs.close();
        return list.toArray(typePro);
    }
    
    /*
    * Devuelve un array de TipoProductoCategoria
    */
    public static TipoProductoCategoria[] getTipoProductoCategoriaFromRS(ResultSet rs) throws SQLException, ParseException{
        List<TipoProductoCategoria> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new TipoProductoCategoria(rs.getInt(1), rs.getInt(2)));
        }
        TipoProductoCategoria[] typeProCat=new TipoProductoCategoria[count];
        rs.close();
        return list.toArray(typeProCat);
    }
    
    /*
    * Devuelve un array de TipoProductoCategoria
    */
    public static TipoProductoTipoAtributo[] getTipoProductoTipoAtributoFromRS(ResultSet rs) 
                                                        throws SQLException, ParseException{
        List<TipoProductoTipoAtributo> list=new ArrayList<>();
        int count=0;
        while(rs.next()) {
            count++;            
            list.add(new TipoProductoTipoAtributo(rs.getInt(1), rs.getInt(2)));
        }
        TipoProductoTipoAtributo[] typeProAtr=new TipoProductoTipoAtributo[count];
        rs.close();
        return list.toArray(typeProAtr);
    }
    
    public static ListWrapper[] getGenericList(ResultSet rs) throws SQLException {
        ArrayList<String[]> lista=new ArrayList<String[]>();
        ResultSetMetaData rsMetaData = rs.getMetaData();
        while(rs.next()) {
            String[] fila=new String[rsMetaData.getColumnCount()];            
            for(int i=0;i<fila.length;i++) {
                fila[i]=rs.getString(i + 1);
            }
            lista.add(fila);
        }       
        return new ListWrapper[]{new ListWrapper(lista)};
    }

    
    
}
